Request structure

This page describes how to build the HTTP/HTTPS request sent by a REST tool. The same fields are configured on the General tab of the tool editor.

Tool parameters

REST tools may have parameters, that the LLM has to specify when calling the tool.

For example, the get_weather tool, used for querying the weather in a specific city in the weather-forecast quickstart, has the city_name parameter that the LLM has to specify every time it calls the tool.

For guidance on which parts of a request to expose as parameters and which to hard-code or drive from variables, see Defining a custom tool.

Default parameter values

To give a parameter a fixed value that the LLM does not choose — and does not even see — set its Description to = followed by the value. For example:

Such a parameter is omitted from the schema exposed to the LLM. Its value is substituted wherever the parameter is referenced and, when the Content field is left empty, it is included in the request body like any other parameter.

Default parameters are convenient for the occasional fixed value, but defining many of them just to assemble a fixed request body is rarely the best approach. In most such cases it is clearer to write the body directly in the Content field, where you have full control over its structure.

Enumerated (ENUM) parameter values

To restrict a parameter to a fixed set of allowed values, start its Description with ENUM: followed by a comma-separated list of the allowed values. The ENUM list ends at the first dot (.) or end of line; the remaining text is the parameter description used by the LLM.

This is supported for parameters of type String, Integer, List of strings and List of integers. For the integer-based types the values are converted to integers, and any non-numeric entry is dropped.

For example, either of the following restricts the parameter to yes or no:

ENUM: yes, no
Customer agreed to participate
ENUM: yes, no. Customer agreed to participate.

The allowed values are exposed to the LLM as part of the tool schema, so the model can only pick one of them.

Request fields

You have full control over the HTTP/HTTPS request structure via the following Tool configuration fields:

Field Description Example
URL Specifies URL where HTTP/HTTPS request is sent.
Must start with http:// or https://.
http://wttr.in/London
Headers Specifies header included in HTTP/HTTPS request. Use name: value format – exactly as included in HTTP request. There typically is no need surround string values in quotes.
Use multiple lines to specify multiple headers.
X-Client-Id: 123456
X-Request-Id: 11-22-33
Content Specifies content of HTTP/HTTPS request. {
"request": "create",
"event": "appointment"
}
Authentication Specifies authentication for HTTP/HTTPS request.
The following authentication methods are supported:
None
Basic
Bearer
OAuth2
Authentication: Bearer
Bearer key: 123456

When specifying values for all these fields, you may reference the tool's parameters, the tool's own variables, or any of the dynamic variables available to the agent or flow (agent / flow variables, conversation data, and so on) by enclosing their name in curly brackets.

For example, you can specify the following for URL:

https://wttr.in/{city}

Referencing values in the Content field

When referencing string parameters or variables in the Content field, the software automatically adds quotes around the value, unless you include them yourself. In other words, the following two options are equivalent — assuming {city} is London, both produce "city": "London" in the request body:

{
   "city": {city}
}
{
   "city": "{city}"
}

Use double curly brackets if you want to reference string parameters or variables “as is” with no quotes being automatically added:

<city>{{city}}</city>

If you leave Content field empty, parameters not explicitly referenced in URL and Headers fields will be included in the request body as JSON dictionary.

“Content-Type: application/json” header is automatically added to the request. But you may override it by specifying a different value in Headers field.

Conditional branching

The URL, Headers and Content fields support conditional branching, so the request can change shape depending on the parameters or variables:

{{#if <condition>}} … {{#elseif <condition>}} … {{#else}} … {{/if}}

For example, the Content field can send a different body depending on a priority parameter:

{
   "order": {order_id},
   {{#if priority == "high"}}
   "queue": "express"
   {{#else}}
   "queue": "standard"
   {{/if}}
}

Time parameters conversion

Use to_utc() and from_utc() functions to convert the time and date parameters between UTC and specific timezone specified via timezone variable.

For example, you may specify the following in Content field:

{
   "start": {to_utc(start)},
   "end": {to_utc(end)}
}

Set the timezone variable in your agent’s configuration screen to a valid timezone name; for example:

timezone = Europe/Paris

If the parameter value passed to to_utc() function contains offset, for example, 2024-01-15T10:00:00+10:00, the timezone variable is ignored.

Both single and double angular brackets are supported by to_utc() and from_utc() functions – similar to string variable expansion.

Nested JSON values

Some APIs expect a JSON object to be sent as a string — a small JSON document carried inside a field of the request body. A value placed there has to be escaped twice: once for the inner document, and once again for the body that contains it. Use the json() function to do both:

{
   "record": "{ \"first_name\": {json(first_name)}, \"note\": {json(note)} }"
}

With {first_name} set to Ann and {note} to Said "yes", that produces:

{
   "record": "{ \"first_name\": \"Ann\", \"note\": \"Said \\\"yes\\\"\" }"
}

json() writes the quotes around the value itself, so do not add your own. Referencing the value with a plain {note} instead would escape it only once, and a quotation mark in it would end the string early and corrupt the request.

If the parameter or variable has no value, {json(name)} is left as it is — wrap it in a conditional block to drop the whole field instead.

Response structure

The HTTP response code indicates whether the request was successful, while the response body contains the tool’s actual output. For best results, format the response body as JSON or XML so the LLM can easily interpret its structure.

You can post-process the response before it reaches the LLM — for example, to extract a single field or trim large payloads. See Customizing tool response.

Defining a custom tool

When defining custom tool that triggers some external API it is important to distinguish between parts of the API request that should be defined as tool parameters and other parts that should be provisioned via request structure fields – URL / Headers / Content / Authentication.

Use the following guidelines when making this decision:

For example, consider the schedule_appointment tool from doctor-clinic quickstart that uses cal.com API and needs to generate the following REST API request:

POST https://api.cal.com/v2/bookings
Authorization: Bearer <api key>
cal-api-version: 2024-08-13
Content-type: application/json

{
    "start": "event start time",
    "eventTypeId": "event type ID",
    "attendee": {
         "name": "name of the attendee",
         "email": "email of the attendee",
         "timezone": "timezone"
    }
}

You typically define it as follows:

Note that we defined only three parameters for the tool – start, name and email. They vary from one tool call to another, and the LLM has to specify them for every tool call.

We are also using the apiKey and event_type_id values. As they are fixed for this tool, define them as tool variables. If the same API key is shared across several tools or differs between agents, define it as an agent variable instead.